home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 001-025 / disk_022 / pemacs / mouse.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  8KB  |  342 lines

  1. /*
  2.  *  This file implements memacs support for the Amiga mouse.
  3.  *  Author:  Andy Poggio
  4.  */
  5.  
  6. #include <exec/types.h>
  7. #include <exec/exec.h>
  8. #include <intuition/intuition.h>
  9. #include <devices/console.h>
  10. #include        <stdio.h>
  11. #include        "ed.h"
  12.  
  13. #define NL 0
  14.  
  15. extern struct Window *Window;
  16.  
  17. /* Font sizes */
  18.  
  19. #define FONT_X 8
  20. #define FONT_Y 8
  21.  
  22. /* Button Codes */
  23.  
  24. #define LEFT_BUTTON 1
  25. #define RIGHT_BUTTON 2
  26.  
  27. /* Menu Definitions */
  28.  
  29.  
  30. #define NUM_MENUS 1
  31.  
  32. /* Copies of this structure will get "stamped" into many more */
  33. /* Allocated later */
  34. struct IntuiText generic = {
  35.   0, 1,                        /* Bluepen, Whitepen */
  36.   JAM2, 5,                     /* mode,  LeftEdge */
  37.   0, NL,                       /* Top (to be filled later), Font */
  38.   NL,                          /* Name (to be filled later) */
  39.   NL                           /* Next one */
  40. };
  41.  
  42. /* Menu numbers */
  43. #define COM_MENU 0
  44.  
  45. /* Menu Widths */
  46. #define COM_WIDTH  72
  47.  
  48. int item_widths[ NUM_MENUS ] = { 112 };
  49.  
  50. /* All items in these menus have the following flags set */
  51. #define BLACK_FILL  ITEMTEXT | ITEMENABLED | HIGHCOMP
  52.  
  53.                             /** FILE MENU ITEMS  **/
  54. #define NUM_COM_ITEMS 9
  55. #define COPY_ITEM       0
  56. #define KILL_ITEM      1
  57. #define UNKILL_ITEM      2
  58. #define TWO_ITEM     3
  59. #define ONE_ITEM      4
  60. #define QUERY_ITEM      5
  61. #define NEW_ITEM      6
  62. #define QUIT_ITEM      7
  63. #define NOOP_ITEM      8
  64.  
  65. struct MenuItem  com_items[NUM_COM_ITEMS];
  66. struct IntuiText com_names[NUM_COM_ITEMS];
  67.  
  68. char  *commenu_names[] = {
  69.    "Copy Region",
  70.    "Kill Region",
  71.    "Un-Kill",
  72.    "Split Window",
  73.    "One Window",
  74.    "Query Replace",
  75.    "New CLI",
  76.    "Quit",
  77.    "No Operaton"
  78. };
  79.  
  80. struct Menu cmenu = {
  81.   NL,                 /* Pointer to next menu */
  82.   0, 0, COM_WIDTH, 10,       /* LeftEdge, TopEdge, Width, Height */
  83.   MENUENABLED,               /* FLAGS */
  84.   "Commands",                    /* Menu name */
  85.   com_items                 /* First item structure */
  86. };
  87.  
  88. mouse_setup_menu()
  89. {
  90.    mouse_newmenu( &cmenu, commenu_names, com_items, com_names,
  91.             NUM_COM_ITEMS, item_widths[0], BLACK_FILL);
  92.    SetMenuStrip(Window, &cmenu);      /* Set up the menu here */
  93. }
  94.  
  95. mouse_clear_menu()
  96. {
  97.     ClearMenuStrip(Window, &cmenu);
  98. }
  99.  
  100. static
  101. do_menu( m, f, n) /* execute a menu command */
  102. {
  103.     int menu, item, sub;
  104.  
  105.     menu = MENUNUM( m);
  106.     item = ITEMNUM( m);
  107.     sub = SUBNUM( m);
  108.  
  109.     switch( menu) {
  110.     case COM_MENU:
  111.         switch( item) {
  112.         case COPY_ITEM:
  113.             copyregion( f, n);
  114.             break;
  115.  
  116.         case KILL_ITEM:
  117.             killregion( f, n);
  118.             break;
  119.  
  120.         case UNKILL_ITEM:
  121.             yank( f, n);
  122.             break;
  123.  
  124.         case TWO_ITEM:
  125.             splitwind( f, n);
  126.             break;
  127.  
  128.         case ONE_ITEM:
  129.             onlywind( f, n);
  130.             break;
  131.  
  132.         case QUERY_ITEM:
  133.             qreplace( f, n);
  134.             break;
  135.  
  136.         case NEW_ITEM:
  137.             spawncli( f, n);
  138.             break;
  139.  
  140.         case QUIT_ITEM:
  141.             quickexit( f, n);
  142.             break;
  143.  
  144.         case NOOP_ITEM:
  145.             break;
  146.         }
  147.         break;
  148.     }
  149. }
  150.  
  151. mouse_handle_event( execute, f, n)
  152. {
  153.     register char *s;
  154.     char instr[ 81]; /* 8 nine digit numbers with separators + 1 */
  155.     int result, c, class, subclass, keycode, qualifiers, x, y, secs, musecs;
  156.     static int netx, nety;
  157.     static int button_now = 0, button_ever = 0;
  158.  
  159.     for( s = instr; (*s++ = ttgetc()) != '|';);
  160.     *s = 0; /* terminate the str */
  161.     if( ! execute) return;
  162.  
  163.     sscanf( instr, "%d;%d;%d;%d;%d;%d;%d;%d|",
  164.      &class, &subclass, &keycode, &qualifiers, &x, &y, &secs, &musecs);
  165.  
  166.     switch( class) {
  167.     case 2: /* mouse button--only get this for left button */
  168.         if( keycode & 0x80) { /* key up */
  169.         keycode &= ~0x80; /* clear the up bit */
  170.         button_now &= ~ LEFT_BUTTON;
  171.         } else { /* key down */
  172.         netx = Window->MouseX - Window->BorderLeft; /* save coords */
  173.         nety = Window->MouseY - Window->BorderTop;
  174.         button_now |= LEFT_BUTTON;
  175.         button_ever |= LEFT_BUTTON;
  176.         }
  177.         break;
  178.  
  179.     case 10: /* menu selection -- right button up only */
  180.         if( keycode == MENUNULL) {
  181.         netx = Window->MouseX - Window->BorderLeft; /* save coords */
  182.         nety = Window->MouseY - Window->BorderTop;
  183.         button_ever |= RIGHT_BUTTON;
  184.         } else { /* made a menu selection */
  185.         button_ever = 0; /* ignore other buttons */
  186.         do_menu( keycode, f, n);
  187.         }
  188.         break;
  189.     }
  190.  
  191.     if(( ! button_now) && button_ever) { /* buttons were pushed: interpret */
  192.     switch( button_ever) {
  193.         case LEFT_BUTTON:
  194.         mouse_to_xy( netx, nety);
  195.         break;
  196.  
  197.         case RIGHT_BUTTON:
  198.         mouse_set_mark( netx, nety);
  199.         break;
  200.  
  201.         case LEFT_BUTTON | RIGHT_BUTTON:
  202.         backdel( f, n);
  203.         break;
  204.     }
  205.     button_ever = 0;
  206.     }
  207. }
  208.  
  209. mouse_newmenu( menu, item_names,  menu_items, menu_text, num_items,
  210.                       Mwidth, flag)
  211. struct Menu      *menu;           /* Menu structure                       */
  212. char            *item_names[];    /* Pointer to array of item names       */
  213. struct MenuItem  menu_items[];    /* pointer to array of structures       */
  214. struct IntuiText menu_text[];     /* Pointer to array of text structures  */
  215. int               num_items;      /* Number of items                      */
  216. int               Mwidth;         /* Menu Width */
  217. int                 flag;         /* Special Item flag for ALL items */
  218. {
  219.     int i;
  220.     int height = 0;
  221.  
  222.     for (i=0; i< num_items; i++) {
  223.  
  224.           menu_text[i] = generic;              /* stamp generic template */
  225.           menu_text[i].IText = (UBYTE *) item_names[i];  /* mv string ptrs */
  226.           menu_items[i].NextItem = &menu_items[i+1];  /* Lnk to nxt item */
  227.           menu_items[i].TopEdge = 10 * i;            /* Top rect of item */
  228.           menu_items[i].LeftEdge = 0;
  229.           menu_items[i].Height = 8;
  230.           menu_items[i].ItemFill = (APTR)&menu_text[i];
  231.           menu_items[i].Flags = flag;
  232.           menu_items[i].Width = Mwidth;
  233.           menu_items[i].MutualExclude = 0x0000;
  234.           menu_items[i].Command = 0;
  235.           menu_items[i].SubItem = NL;
  236.           menu_items[i].NextSelect = NL;
  237.           height += 10;
  238.     }
  239.     menu_items[num_items-1].NextItem = NULL;
  240.     menu->Height = height;
  241. }
  242.  
  243. static
  244. winddist( w, row, col) /* calc distance of window from this row, col */
  245. WINDOW *w;
  246. {
  247.     int d;
  248.  
  249.     if( row < w->w_toprow) /* above window */
  250.     return( w->w_toprow - row);
  251.     else if( row < (w->w_toprow + w->w_ntrows)) /* within window */
  252.     return( 0);
  253.     else /* below window */
  254.     return( row - (w->w_toprow + w->w_ntrows));
  255. }
  256.  
  257. WINDOW *
  258. mouse_find_wind( row, col) /* find window containing this row, col */
  259. {
  260.     WINDOW *w, *result_w;
  261.     int distance, result_distance;
  262.  
  263.     result_distance = HUGE; /* greater than any real distance */
  264.     for( w = wheadp; w != NULL; w = w->w_wndp) {
  265.     distance = winddist( w, row, col);
  266.     if( distance < result_distance) {
  267.         result_w = w;
  268.         result_distance = distance;
  269.     }
  270.     }
  271.     return( result_w);
  272. }
  273.  
  274. static
  275. get_wintop( this_w) /* return row for top of this window */
  276. WINDOW *this_w;
  277. {
  278.     register WINDOW *w;
  279.     register int row;
  280.  
  281.     row = 0;
  282.     for( w = wheadp; w != this_w; w = w->w_wndp) {
  283.     row += w->w_ntrows +1;
  284.     }
  285.     return( row);
  286. }
  287.  
  288. mouse_to_xy( x, y) /* move point to position at coords x,y */
  289. {
  290.     register LINE   *dlp;
  291.     register int row, col;
  292.     WINDOW *w;
  293.  
  294.     row = y / FONT_Y; /* convert coords to row and col */
  295.     col = x / FONT_X;
  296.  
  297.     w = mouse_find_wind( row, col); /* find the window and make it current */
  298.     curwp = w;
  299.     curbp = curwp->w_bufp;
  300.  
  301.     row -= get_wintop( curwp); /* adjust to row in window */
  302.     if( row >= curwp->w_ntrows) row = curwp->w_ntrows -1;
  303.  
  304.     dlp = curwp->w_linep;
  305.     while (row-- && dlp!=curbp->b_linep) {
  306.                 dlp = lforw(dlp);
  307.     }
  308.     curwp->w_dotp  = dlp;
  309.     curgoal = col; /* aim for this col */
  310.     curwp->w_doto  = getgoal(dlp);
  311. }
  312.  
  313. mouse_set_mark( x, y) /* set mark at mouse cursor */
  314. {
  315.     WINDOW *wp;
  316.     LINE *dlp;
  317.     int offset;
  318.  
  319.     /* save current position */
  320.     wp = curwp;
  321.     dlp = curwp->w_dotp;
  322.     offset = curwp->w_doto;
  323.  
  324.     /* go to cursor position, set mark, and announce */
  325.     mouse_to_xy( x, y);
  326.     update();
  327.     setmark( FALSE, 1);
  328.     update();
  329.  
  330.     /* return to former position */
  331.     curwp = wp;
  332.     curbp = curwp->w_bufp;
  333.     curwp->w_dotp = dlp;
  334.     curwp->w_doto = offset;
  335. }
  336.  
  337. mouse_enable() /* this must be last to keep ctags happy */
  338. {
  339.     ttputs( "0{");    /* get mouse button and menu events */
  340.     ttflush();
  341. }
  342.